/** uni 函数库 */
declare interface Uni {
    /** 函数库 */
    $u: design;
}

/**
 * 函数库
 */
type design = {
    api: any;
    /**
     * 显示信息
     * @param word 标题
     * @param mask 不允许穿透
     * @param icon 图标
     */
    toast(word: string, mask?: boolean, icon?: any): void;
    /**
     * 对象转url参数
     * @param data,对象
     * @param isPrefix,是否自动加上"?"
     * @param arrayFormat,默认值:repeat;可选值有4个：indices，brackets，repeat，comma
     */
    queryParams(data: any, isPrefix?: boolean, arrayFormat?: string): string;
    /**
     * 全局唯一标识符
     * @param len       uuid的长度
     * @param firstU    将返回的首字母置为"u"
     * @param radix     生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
     */
    guid(len?: number, firstU?: boolean, radix?: number): string;
    /**
     * 随机数
     * @param min 最小值，最小值可以等于该值
     * @param max 最大值，最大值可以等于该值
     * @return    随机数
     */
    random(min: number, max: number): number;
    /**
     * 防抖原理：一定时间内，只有最后一次操作，再过wait毫秒后才执行函数
     *
     * @param {Function} func 要执行的回调函数
     * @param {Number} wait 延时的时间
     * @param {Boolean} immediate 是否立即执行
     */
    debounce(func: Function, wait?: number, immediate?: boolean): void;
    /**
     * 节流函数
     * 节流原理：在一定时间内，只能触发一次
     * @param {Function}  func      要执行的回调函数
     * @param {Number}    wait      延时的时间
     * @param {Boolean}   immediate 是否立即执行
     */
    throttle(func: Function, wait?: number, immediate?: boolean): void;
    /**
     * 深度克隆
     * @param obj Object
     */
    deepClone(obj: any): Object;
    /**
     * 打电话
     * @param {String<Number>} phoneNumber - 数字字符串
     * @return Promise<boolean>
     */
    callPhone(phoneNumber: string): Promise<boolean | any>;
    /**
     * 调起客户端相机扫码。
     * @description https://uniapp.dcloud.net.cn/api/system/barcode.html
     * @param {Boolean} onlyFromCamera true 是否只允许相机扫码识别
     * @param {Array<string>} scanType ['barCode', 'qrCode', 'datamatrix','datamatrix']
     * @return Promise 成功返回相关数据结构
     */
    scanCode(onlyFromCamera: boolean, scanType: Array<any>): Promise<UniApp.ScanCodeSuccessRes | string>;
    /**
     * 获取屏幕窗口安全高度和宽度
     * 注意是针对种屏幕的统一计算，统一高度，不再让uni获取有效高度而烦恼。
     * 请一定要在onMounted或者onLoad中调用，否则不准确在h5端。
     * @return {height,width,top,isCustomHeader,sysinfo}
     */
    window(): {
        width: number;
        height: number;
        top: number;
        bottom: number;
        isCustomHeader: Boolean;
        sysinfo: UniApp.GetSystemInfoResult;
    };
    /**
     * 剪切板
     */
    clipboard: clipboard;
    /**
     * 数组
     */
    array: array;
    /**
     * 时间
     */
    time: time;
    /**
     * 路由跳转
     * @param options 路由地址或者路由参数
     * @param params  传递的对象形式的参数，如{name: 'lisa', age: 18}
     */
    route: (options: any, params?: any) => Promise<void>;
    /**
     * http数据请求
     */
    http: http;
    /**
     * 弹窗提示
     */
    alert: alert;
    /**
     * 本地数据缓存
     */
    storage: storage;
    /**
     * 规则校验
     */
    test: test;
    //pagejson下的pages配置。
    pages: Array<{ path: string; custom: 'custom' | 'default' }>;
    //pagejson下的配置。
    tabBar: tabBarType;
    /**
     * 判断是否是颜色值
     * @param color 颜色值
     */
    isColor(color: string): boolean;
    /**
     * 国际化
     * @param key 关键字
     * @return 语言值
     */
    language(key: string): string;
    tmicon: Array<{
        font: string;
        prefix: string;
        fontJson: Array<{
            icon_id: string;
            name: string;
            font_class: string;
            unicode: string;
            unicode_decimal: number;
        }>;
    }>;
};

/**
 * 本地数据缓存
 */
type storage = {
    /**
     * @description 设置缓存
     * @param {string} key 缓存键
     * @param {*} value 缓存值
     * @param expire
     */
    set(key: string, value: any, expire?: number): any;
    /**
     * 读取缓存
     * @param {string} key 缓存键
     * @param {*=} def 默认值
     */
    get(key: string, def?: any): any;
    /**
     * 从缓存删除某项
     * @param {string} key
     */
    remove(key: string): any;
    /**
     * 清空所有缓存
     * @memberOf Cache
     */
    clear(): void;
};

/**
 * 弹窗提示
 */
type alert = {
    /**
     * 消息弹窗提示
     * @param msg         提示内容
     * @param showCancel  是否显示取消按钮，默认为 true
     * @param okLabel     确定按钮的文字，默认为"确定"
     * @param cancel      取消按钮的文字，默认为"取消"
     * @returns           Promise
     */
    confirm(msg: string, showCancel?: boolean, okLabel?: string, cancel?: string): Promise<any>;
    /**
     * 提示消息
     * @param msg         提示内容
     * @param showCancel  是否显示取消按钮，默认为 false
     * @param okLabel     确定按钮的文字，默认为"确定"
     * @returns           Promise
     */
    info(msg: string, showCancel?: boolean, okLabel?: string): Promise<any>;
    /**
     * 警告提示
     * @param msg         提示内容
     * @param showCancel  是否显示取消按钮，默认为 false
     * @param okLabel     确定按钮的文字，默认为"确定"
     * @returns           Promise
     */
    warning(msg: string, showCancel?: boolean, okLabel?: string): Promise<any>;
    /**
     * 成功提示
     * @param msg         提示内容
     * @param showCancel  是否显示取消按钮，默认为 false
     * @param okLabel     确定按钮的文字，默认为"确定"
     * @returns           Promise
     */
    success(msg: string, showCancel?: boolean, okLabel?: string): Promise<any>;
    /**
     * 错误提示
     * @param msg     提示内容
     */
    error(msg: string): void;
};

/**
 * http数据请求
 */
type http = {
    /**
     * GET请求
     * @param url 请求地址
     * @param data 请求的数据
     * @param opts 请求的配置
     */
    get<T>(url: string, data?: object, opts?: fetchConfig): Promise<T>;
    /**
     * POST请求
     * @param url 请求地址
     * @param data 请求的数据
     * @param opts 请求的配置
     */
    post<T>(url: string, data?: object, opts?: fetchConfig): Promise<T>;
    /**
     * 自定义请求
     * @param cog 请求的配置
     * @param beforeFun 请求前执行的函数
     * @param afterFun 请求后执行的函数
     * @param complete 请求完成的函数
     */
    request<T>(cog: fetchConfig, beforeFun?: Function, afterFun?: Function, complete?: Function): Promise<T>;
};

/**
 * 规则校验
 */
type test = {
    /**
     * 是否是邮箱
     * @param   value     字符串
     * @returns Boolean
     */
    email(value: string): boolean;
    /**
     * 是否是手机号
     * @param   value     手机号
     * @returns Boolean
     */
    mobile(value: string | number): boolean;
    /**
     * 是否是URL
     * @param   value     字符串
     * @returns Boolean
     */
    url(value: string): boolean;
    /**
     * 是否含有中文
     * @description 可以为单个汉字，或者汉字组成的字符串
     * @param   value     字符串
     * @returns Boolean
     */
    chinese(value: string): boolean;
    /**
     * 是否是车牌
     * @description 蓝牌5位，绿牌6位。
     * @param   value     字符串
     * @returns Boolean
     */
    carNo(value: string): boolean;
    /**
     * 是否身份证号
     * @param   value       字符串或者数字
     * @returns Boolean
     */
    idCard(value: string | number): boolean;
    /**
     * 是否是日期格式
     * @description 验证一个字符串是否日期
     * @param   value       字符串，数字，日期对象
     * @returns Boolean
     */
    date(value: string | number | Date): boolean;
    /**
     * 判断是否为空
     * @description 判断是否是null,对象是否为空，数组是否为空。是否为 undefaind，是否为 “”空字符串。
     * @param   value   任意
     * @returns Boolean
     */
    isEmpty(value: any): boolean;
    /**
     * 是否是十进制数字
     * @description 整数，小数，负数，带千分位数(2,359.08)等可以检验通过
     * @param   value     字符串或者数字
     * @returns Boolean
     */
    number(value: string | number): boolean;
    /**
     * 是否是整数
     * @description 所有字符都在0-9之间，才校验通过
     * @param   value     字符串或者数字
     * @returns Boolean
     */
    digits(value: string | number): boolean;
    /**
     * 是否是金额
     * @description 只允许最多两位小数，可以带千分位
     * @param   value     字符串或者数字
     * @returns Boolean
     */
    amount(value: string | number): boolean;
    /**
     * 是否是字母
     * @description 只能为"a-z"或者"A-Z"之间的字符
     * @param   value     字符串
     * @returns Boolean
     */
    letter(value: string): boolean;
    /**
     * 是否是字母或者数字
     * @description 只能是字母或者数字
     * @param   value     字符串
     * @returns Boolean
     */
    enOrNum(value: string): boolean;
    /**
     * 是否包含某个值
     * @description 字符串中是否包含某一个子字符串，区分大小写
     * @param str           字符串
     * @param subStr        子字符串
     * @returns Boolean
     */
    contains(str: string, subStr: string): boolean;
    /**
     * 数值是否在某个范围内
     * @description 如30在"29-35"这个范围内，不在"25-28"这个范围内
     * @param value     数值
     * @param param     如"[25-35]"
     * @returns Boolean
     */
    range(value: number, param: Array<number>): boolean;
    /**
     * 字符串长度是否在某个范围内
     * @description 如"abc"长度为3，范围在"2-5"这个区间
     * @param value     字符串
     * @param param     如"[25, 35]"
     * @returns Boolean
     */
    rangeLength(value: string, param: Array<number>): boolean;
    /**
     * 是否是json字符串
     * @description 校验是否Json字符串
     * @param   value     字符串
     * @returns Boolean
     */
    jsonString(value: string): boolean;
    /**
     * 是否是数组
     * @description 校验是否数组
     * @param   value     任意
     * @returns Boolean
     */
    array(value: any): boolean;
    /**
     * 是否是对象
     * @description 校验是否对象
     * @param   value     任意
     * @returns Boolean
     */
    object(value: any): boolean;
    /**
     * 纯数字密码验证
     * @param s 字符串或者数字
     * @param len 最小长度，默认6
     * @param maxLen 最大长度，默认20
     * @returns Boolean
     */
    passwordOfNumber(s: number | string, len?: number, maxLen?: number): boolean;
    /**
     * 密码验证(长度6-20)
     * @param s 字符串或者数字
     * @param model 0、包含数字和英文; 1、包含数字，英文，不允许有特殊字符; 2、包含数字和字母，可以有特殊字符。
     * @returns Boolean
     */
    passwordOfOther(s: string | number, model?: number): boolean;
    /**
     * 是否是短信验证码
     * @description 短信验证码
     * @param   value     字符串
     * @param   len       验证码长度，默认为6
     * @returns Boolean
     */
    code(value: string, len?: number): boolean;
};

/**
 * 剪贴板
 */
type clipboard = {
    /**
     * 设置剪切板内容。
     * @param {String} data
     * @returns Promise true/false
     */
    set(data: string): Promise<boolean | string>;
    /**
     * 获取剪切板内容
     * @returns Promise 剪切板内容
     */
    get(): Promise<string | boolean>;
};

/**
 * 数组
 */
type array = {
    /**
     * 数据分组
     * @param {Array} oArr - 原数组列表
     * @param {Number} length - 单个数组长度
     * @return {Array}  arr - 分组后的新数组
     */
    splitData(oArr: Array<any>, length: number): Array<any>;
};

/**
 * 时间
 */
type time = {
    /**
     * 获取时间距离当前时间
     * @param timestamp 当前时间
     * @return 返回比如：不久前，1年前这样的格式文本
     */
    getFrom(timestamp?: number | string | Date): string;
    /**
     * 剩余时间格式化
     * @param {Number} t - 剩余多少秒
     * @return {Object}  format - 格式后的天时分秒对象
     */
    getMuch(t: number): string;
};

/**
 * uni 命名空间
 */
declare namespace UniNamespace {
    interface CanvasToTempFilePathOptions {
        canvas?: CanvasContext;
    }
    interface CanvasContext {
        width: number;
        height: number;
        dpr: number;
        toTempFilePath(
            any0: any,
            any1: any,
            any2: any,
            any3: any,
            any4: any,
            any5: any,
            any6: any,
            any7: any,
            any8: any,
        ): void;
    }
    interface NodesRef {
        node(callback?: (result: any) => void): SelectorQuery;
        fields(fields: NodeField, callback?: (result: NodeInfo) => void): SelectorQuery;
    }
    interface NodeField {
        node?: boolean;
    }
}

type pagesCustomType = 'default' | 'custom';
type pagesType = {
    //页面地址
    path: string;
    //导航栏模式
    custom: pagesCustomType;
    navigationBarBackgroundColor: string;
    navigationBarTextStyle: string;
    subPackages?: Array<any>;
};
type tabBarItemType = {
    pagePath: string;
    iconPath: string;
    selectedIconPath: string;
    text: string;
};
type tabBarType = {
    color: string;
    selectedColor: string;
    borderStyle: string;
    backgroundColor: string;
    list?: Array<tabBarItemType>;
};

type fetchConfigResponseType = 'arraybuffer' | 'text';
type fetchConfigDataType = 'json' | 'text';
type fetchConfigMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'HEAD' | 'OPTIONS' | 'TRACE';

interface fetchConfigSuccessType {
    data: object | string | ArrayBuffer;
    statusCode: number;
    header: object;
    cookies: Array<string>;
}
interface fetchConfig {
    url?: string;
    data?: object | string | ArrayBuffer;
    header?: object;
    method?: fetchConfigMethod;
    timeout?: number;
    dataType?: fetchConfigDataType;
    responseType?: fetchConfigResponseType;
    sslVerify?: boolean;
    withCredentials?: boolean;
    firstIpv4?: boolean;
    success?: Function;
    fail?: Function;
    complete?: Function;
}
type openUrlType = 'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab' | 'navigateBack';
declare interface Touch {
    readonly clientX: number;
    readonly clientY: number;
    readonly force: number;
    readonly identifier: number;
    readonly pageX: number;
    readonly pageY: number;
    readonly radiusX: number;
    readonly radiusY: number;
    readonly rotationAngle: number;
    readonly screenX: number;
    readonly screenY: number;
    readonly target: EventTarget;
    readonly x: number;
    readonly y: number;
}

declare interface TouchEvent {
    readonly changedTouches: TouchList;
}
